import os

import pymysql
from datetime import timedelta

# 项目基础配置
# * 若移动文件夹需要修改部分配置，静态文件等基础配置已移除，debug需要在生产环境修改为False，settings目录下创建了不同环境的配置，
# * 可以根据需求覆盖掉base.py文件的配置。
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SECRET_KEY = '+o5pyv*&rv*36o0$qnlo8vk^u9bjz1&jqhweg3ka%zke@5m8jn'
ISS_KEY = 'asdqk112301ma0'
USE_KEY = 'asdqk112301ma0'
ROOT_URLCONF = 'application.urls'
WSGI_APPLICATION = 'application.wsgi.application'
ASGI_APPLICATION = 'application.routing.application'
DEBUG = True
ALLOWED_HOSTS = []

# 时区设置
# * 以下配置无须修改。
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False

# app
# * django自带的app功能已全部删除，如果想用请参考文档自行添加，THIRD_APPS为第三方的模块，PROJECT_APPS为项目app。
THIRD_APPS = [
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django_comment_migrate',
    'django_filters',
    'rest_framework',
    'channels',
    'corsheaders',  # 注册跨域app
]

PROJECT_APPS = [
    'system.home',
    'system.user',
    'system.role',
    'system.menu',
    'system.oplog',
    'system.host',
    'system.file',
    'system.settings',
    'system.project',
    'main.script',
    'main.alarm',
    'main.task',
]

INSTALLED_APPS = THIRD_APPS + PROJECT_APPS

# 解决跨域问题
CORS_ORIGIN_ALLOW_ALL = True
# 中间件
# * django自带的中间件已全部删除，需要使用参考django文档自行添加自定义中间件。
MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',  # 跨域中间件
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'utils.middleware.ApiLoggingMiddleware',  # 日志记录中间件
]

# 数据库
# * 使用pymysql过滤报错，如果考虑效率，可以不使用pymysql，网上有如何使用mysqldb的教程，因为实现方式不同，mysqldb的效率高于pymysql。
pymysql.install_as_MySQLdb()
DATABASES = {
    'default': {
        'ATOMIC_REQUESTS': True,
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

# 缓存
CACHES = {'default': {}}

# Django rest framework 框架配置
# * UNAUTHENTICATED_USER、UNAUTHENTICATED_TOKEN、DEFAULT_AUTHENTICATION_CLASSES不使用，因为其中的部分方法引用了django自带的app，
# * 所以将其至为空后，可以不使用django自带的app方法。
REST_FRAMEWORK = {
    'DATETIME_FORMAT': "%Y-%m-%d %H:%M:%S",  # 日期时间格式配置
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ],
    'EXCEPTION_HANDLER': 'utils.exc.CustomExceptionHandler',
    'DEFAULT_PAGINATION_CLASS': 'utils.pagination.CustomPagination',  # 自定义分页
    'DEFAULT_FILTER_BACKENDS': (
        'django_filters.rest_framework.DjangoFilterBackend',
        # 'utils.filters.CustomDjangoFilterBackend',
        'rest_framework.filters.SearchFilter',
        'rest_framework.filters.OrderingFilter',
    )  # 过滤后台
    # 'EXCEPTION_HANDLER': 'utils.exception.custom_exception_handler',
    # 'DEFAULT_RENDERER_CLASSES': [
    #     'rest_framework.renderers.JSONRenderer',
    # ],
}

# 日志配置
# * logging模块配置中`loggers`定义了两个日志，分别是`django`以及`lamp`，lamp为本项目名称，接口中日志使用lamp，django为django系统自带
# * 的日志，需要关闭掉django自带日志的影响，但是对于django异常警告，还是会打印，仅过滤Django框架INFO级别的日志。方便自定义日志中间件或者记
# * 录接口相关日志，关于异常的堆栈信息保存在日志文件中，终端的打印中不会出现堆栈信息。
# log 配置部分BEGIN #
SERVER_LOGS_FILE = os.path.join(BASE_DIR, 'logs', 'api.log')
ERROR_LOGS_FILE = os.path.join(BASE_DIR, 'logs', 'error.log')
if not os.path.exists(os.path.join(BASE_DIR, 'logs')):
    os.makedirs(os.path.join(BASE_DIR, 'logs'))

# 格式:[2020-04-22 23:33:01][micoservice.apps.ready():16] [INFO] 这是一条日志:
# 格式:[日期][模块.函数名称():行号] [级别] 信息
STANDARD_LOG_FORMAT = '[%(asctime)s][%(name)s.%(funcName)s():%(lineno)d] [%(levelname)s] %(message)s'
CONSOLE_LOG_FORMAT = '[%(asctime)s][%(name)s.%(funcName)s():%(lineno)d] [%(levelname)s] %(message)s'

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': STANDARD_LOG_FORMAT
        },
        'console': {
            'format': CONSOLE_LOG_FORMAT,
            'datefmt': '%Y-%m-%d %H:%M:%S',
        },
        'file': {
            'format': CONSOLE_LOG_FORMAT,
            'datefmt': '%Y-%m-%d %H:%M:%S',
        },
    },
    'handlers': {
        'file': {
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': SERVER_LOGS_FILE,
            'maxBytes': 1024 * 1024 * 100,  # 100 MB
            'backupCount': 5,  # 最多备份5个
            'formatter': 'standard',
            'encoding': 'utf-8',
        },
        'error': {
            'level': 'ERROR',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': ERROR_LOGS_FILE,
            'maxBytes': 1024 * 1024 * 100,  # 100 MB
            'backupCount': 3,  # 最多备份3个
            'formatter': 'standard',
            'encoding': 'utf-8',
        },
        'console': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'console',
        }
    },
    'loggers': {
        # default日志
        '': {
            'handlers': ['console', 'error', 'file'],
            'level': 'INFO',
        },
        'django': {
            'handlers': ['console', 'error', 'file'],
            'level': 'INFO',
        },
        'scripts': {
            'handlers': ['console', 'error', 'file'],
            'level': 'INFO',
        },
        # 数据库相关日志
        'django.db.backends': {
            'handlers': [],
            'propagate': True,
            'level': 'INFO',
        },
    }
}

# 登录方式配置
AUTHENTICATION_BACKENDS = [
    'utils.backends.CustomBackend'
]

# simplejwt配置
SIMPLE_JWT = {
    # token有效时长
    'ACCESS_TOKEN_LIFETIME': timedelta(days=1),
    # token刷新后的有效时间
    'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
    # 设置前缀
    'AUTH_HEADER_TYPES': ('JWT',),
    'ROTATE_REFRESH_TOKENS': True
}

# 配置生产环境和开发环境,对应不同的配置文件,可在config下的py文件中配置
try:
    if os.environ.get('OPS_ENV', None):
        from conf.production import *
    else:
        from conf.development import *
except ImportError:
    pass

# 其他配置
TABLE_PREFIX = 'system_'
OTHER_TABLE_PREFIX = 'devops_'
AUTH_USER_MODEL = 'user.Users'
INITIALIZE_RESET_LIST = []
API_LOG_ENABLE = True  # 是否开启记录操作日志
API_LOG_METHODS = ['POST', 'UPDATE', 'DELETE', 'PUT']  # 需要日志记录请求方式

REQUEST_KEY = 'devops_api:request'

API_MODEL_MAP = {
    "/token/": "登录模块",
    "/account/login": "登录模块",
    "/system/file/object/": "文件管理",
    "/system/script/exec": "脚本执行"
}
